package com.polaris.live.ui.party.widget

import android.animation.ObjectAnimator
import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.animation.LinearInterpolator
import android.widget.FrameLayout
import android.widget.RelativeLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.BarUtils
import com.blankj.utilcode.util.ScreenUtils
import com.bumptech.glide.Glide
import com.polaris.live.R
import com.polaris.live.cache.CommonCache
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.ext.autoDp
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.mvvm.viewmodel.BaseViewModel
import com.polaris.live.common.util.AppCodeUtils
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.databinding.PopupNewEmojiGuideBinding
import com.polaris.live.databinding.WidgetPartyAnchorBottomBinding
import com.polaris.live.im.manager.ImSessionManager
import com.polaris.live.resp.back_resp.UserFreeGiftResp
import com.polaris.live.resp.back_resp.UserRoomThemeResp
import com.polaris.live.utils.RichCharmImgUtil
import com.polaris.live.utils.image.ImageUtils
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * 房主端底部
 * @author Created by 天晴 on 2024/2/26 15:17
 * @since 1.0.0
 **/
class PartyBottomView(context: Context?, attrs: AttributeSet?) :
    RelativeLayout(context, attrs), LifecycleOwner {

    private var viewModel: BaseViewModel? = null

    private val lifecycleRegistry = LifecycleRegistry(this)

    val mBinding = WidgetPartyAnchorBottomBinding.inflate(LayoutInflater.from(context), this)

    private lateinit var mBuilder: Builder

    //显示发送消息按钮
    private var senderData = MutableLiveData<Boolean>()

    //显示麦克风按钮
    private var mikeData = MutableLiveData<Boolean>()

    /**
     * 麦位状态
     * * 0闭麦 1开麦 2禁麦
     */
    private var mikeStateData = MutableLiveData<Int>()

    //显示表情按钮
    private var emojiData = MutableLiveData<Boolean>()

    //显示消息按钮
    private var messageData = MutableLiveData<Boolean>()

    //显示游戏按钮
    private var gameData = MutableLiveData<Boolean>()

    //显示礼物
    private var giftData = MutableLiveData<Boolean>()

    //显示管理
    private var settingData = MutableLiveData<Boolean>()

    private var freeGiftJob: Job? = null
    private var newEmojiJob: Job? = null
    private var mSourceType: Int = 0 //礼物来源

    private var mSkinMikeClose: String? = null
    private var mSkinMikeOpen: String? = null
    private var mSkinMikeBan: String? = null

    private var mMikeState: Int? = null

    init {
        initListener()
        initObserve()
    }

    /**
     * 初始化
     */
    fun initialize(builder: Builder, viewModel: BaseViewModel) {
        mBuilder = builder
        this.viewModel = viewModel
        initView(builder)
    }

    private fun initView(builder: Builder) {
        builder.apply {
            senderData.value = showSendr
            mikeData.value = showMike
            mikeStateData.value = mikeState
            emojiData.value = showEmoji
            messageData.value = showMessage
            gameData.value = showGame
            settingData.value = showSetting
            giftData.value = showGift
            mSourceType = sourceType
        }
        if (messageData.value == true) {
            updateMessageNumber(ImSessionManager.getTotalUnreadCount())
        }
    }

    /**
     * 是否显示控制按钮
     */

    fun showSettingButton(pd: Boolean) {
        settingData.value = pd
    }

    /**
     * 是否显示游戏按钮
     */

    fun showEmojiButton(pd: Boolean) {
        emojiData.value = pd
    }

    /**
     * 是否显示麦克风按钮
     */
    fun showMikeButton(pd: Boolean) {
        mikeData.value = pd
    }

    /**
     * 是否显示游戏按钮
     */
    fun showGameButton(pd: Boolean) {
        gameData.value = pd
    }

    /**
     * 设置麦克风状态
     */
    fun setMikeState(mike: Int) {
        mikeStateData.value = mike
    }

    /**
     * 设置背包红点
     */
    fun setBackPackRed(visibility: Int) {
        mBinding.backpackRed.visibility = visibility
    }

    /**
     * 设置设置红点
     */
    fun setSettingRed(visibility: Int) {
        mBinding.settingRed.visibility = visibility
    }

    private fun updateMessageNumber(number: Long) {
        if (messageData.value == true) {
            if (number == 0L) {
                mBinding.ivMessageNumber.visibility = View.INVISIBLE
            } else {
                mBinding.ivMessageNumber.visibility = View.VISIBLE
                mBinding.ivMessageNumber.text = if (number > 99) {
                    "99+"
                } else {
                    number.toString()
                }
            }
        }
    }

    private fun initObserve() {
        ImSessionManager.observeUnreadCount(this) { totalUnreadCount, _, _, _ ->
            updateMessageNumber(totalUnreadCount)
        }
    }

    private fun initData() {
        senderData.observe(this) {
            mBinding.sendr.visibility = if (it) View.VISIBLE else View.GONE
        }
        mikeData.observe(this) {
            mBinding.mike.visibility = if (it) View.VISIBLE else View.GONE
        }
        emojiData.observe(this) {
            mBinding.emoji.visibility = if (it) View.VISIBLE else View.GONE
            if (it) {
                showNewEmojiTips()
            }
        }
        messageData.observe(this) {
            mBinding.message.visibility = if (it) View.VISIBLE else View.GONE
        }
        gameData.observe(this) {
            mBinding.game.visibility = if (it) View.VISIBLE else View.GONE
        }
        settingData.observe(this) {
            mBinding.setting.visibility = if (it) View.VISIBLE else View.GONE
        }
        giftData.observe(this) {
            mBinding.gift.visibility = if (it) View.VISIBLE else View.GONE
        }
        mikeStateData.observe(this) {
            mMikeState = it
            mikeStateUI()
        }
    }

    private fun mikeStateUI() {
        when (mMikeState) {
            0 -> {
                if (!mSkinMikeClose.isNullOrEmpty()) {
                    Glide.with(context).load(mSkinMikeClose).into(mBinding.mike)
                } else {
                    mBinding.mike.setImageResource(R.drawable.party_micro_close)
                }
            }

            1 -> {
                if (!mSkinMikeOpen.isNullOrEmpty()) {
                    Glide.with(context).load(mSkinMikeOpen).into(mBinding.mike)
                } else {
                    mBinding.mike.setImageResource(R.drawable.party_micro_open)
                }
            }

            2 -> {
                if (!mSkinMikeBan.isNullOrEmpty()) {
                    Glide.with(context).load(mSkinMikeBan).into(mBinding.mike)
                } else {
                    mBinding.mike.setImageResource(R.drawable.party_micro_ban)
                }
            }
        }
    }

    private var emojiTipsView: View? = null

    /**
     * 显示新表情包提示
     */
    private fun showNewEmojiTips() {
        val level = RichCharmImgUtil.getCommonRichImg(UserManager.getUser().account?.richs ?: 0)
        if (CommonCache.getNewEmojiTips() || level.first < 17) return //显示过了不显示 豪等级不足17
        mBinding.emoji.post {
            val location = IntArray(2)
            mBinding.emoji.getLocationOnScreen(location)
            val emojiX = location[0]
            val emojiY = location[1]
            val rootView = (context as? Activity)?.window?.decorView?.findViewById<ViewGroup>(android.R.id.content)
            if (emojiTipsView != null) {
                rootView?.removeView(emojiTipsView)
            }

            val bind = PopupNewEmojiGuideBinding.inflate(LayoutInflater.from(context), null, false)
            val lp = FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
            ).apply {
                topMargin = emojiY - 4.autoDp - BarUtils.getStatusBarHeight()
                if (AppCodeUtils.isAR()) {
                    rightMargin = ScreenUtils.getScreenWidth() - emojiX - mBinding.emoji.width / 2
                } else {
                    leftMargin = emojiX
                }

            }
            bind.root.layoutParams = lp
            bind.root.visibility = INVISIBLE
            emojiTipsView = bind.root
            bind.root.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    bind.root.viewTreeObserver.removeOnGlobalLayoutListener(this)
                    val lp2 = bind.root.layoutParams as MarginLayoutParams
                    if (AppCodeUtils.isAR()) {
                        lp2.rightMargin =
                            ScreenUtils.getScreenWidth() - emojiX - (bind.root.width + mBinding.emoji.width) / 2
                    } else {
                        lp2.leftMargin = emojiX - (bind.root.width - mBinding.emoji.width) / 2
                    }

                    bind.root.layoutParams = lp2
                    bind.root.post {
                        bind.root.visibility = VISIBLE
                    }
                }
            })

            rootView?.addView(bind.root)
            newEmojiJob = viewModel?.viewModelScope?.launch {
                delay(3000)
                withContext(CoroutineScopeManager.mainDispatcher) {
                    if (emojiTipsView != null) {
                        rootView?.removeView(emojiTipsView)
                        emojiTipsView = null
                    }
                }
            }
            CommonCache.saveNewEmojiTips(true)
        }

    }

    fun inspectFreeGift() {
        viewModel?.let { it1 ->
            mBinding.widgetCircleGift.initFreeGift(mSourceType, it1)
            mBinding.widgetCircleGift.setOnShowViewCallback {
                val isNeedShow = CommonCache.getShowFreeGiftTip()
                if (!isNeedShow) {
                    CommonCache.saveShowFreeGiftTip(true)
                    mBinding.widgetCircleGift.post {
                        val rightMargin =
                            mBinding.llItemMore.width - mBinding.widgetCircleGift.right + (mBinding.widgetCircleGift.width / 2) - 3.autoDp
                        val layoutParam = mBinding.ivBottom.layoutParams as ConstraintLayout.LayoutParams
                        layoutParam.marginEnd = rightMargin
                        mBinding.ivBottom.layoutParams = layoutParam
                        mBinding.cosTip.visibility = View.VISIBLE
                    }
                    shakeView()
                    freeGiftJob = viewModel?.viewModelScope?.launch {
                        delay(10000)
                        withContext(CoroutineScopeManager.mainDispatcher) {
                            mBinding.cosTip.visibility = GONE
                        }
                    }
                }
            }
        }
    }

    fun shakeView() {
        // 创建ObjectAnimator
        val shake = ObjectAnimator.ofFloat(mBinding.cosTip, "translationY", 0f, 20f, 0f)
        shake.duration = 2500 // 动画持续时间
        shake.interpolator = LinearInterpolator() // 设置平滑过渡
        shake.repeatCount = ObjectAnimator.INFINITE // 无限循环
        shake.repeatMode = ObjectAnimator.RESTART // 重复模式为重启
        shake.start() // 启动动画
    }

    fun setTheme(resp: UserRoomThemeResp? = null) {
        if (resp != null) {
            Glide.with(context).load(ImageUtils.imgPath(resp.prefix + resp.send))
                .placeholder(R.drawable.party_message).into(mBinding.sendr)
            Glide.with(context).load(ImageUtils.imgPath(resp.prefix + resp.emoji))
                .placeholder(R.drawable.party_emoji).into(mBinding.emoji)
            Glide.with(context).load(ImageUtils.imgPath(resp.prefix + resp.chat))
                .placeholder(R.drawable.party_message2).into(mBinding.ivMessage)
            Glide.with(context).load(ImageUtils.imgPath(resp.prefix + resp.more))
                .placeholder(R.drawable.party_more).into(mBinding.ivMore)

            mSkinMikeOpen = ImageUtils.imgPath(resp.prefix + resp.mic)
            mSkinMikeClose = ImageUtils.imgPath(resp.prefix + resp.micClose)
            mSkinMikeBan = ImageUtils.imgPath(resp.prefix + resp.micBan)
        } else {
            mBinding.sendr.setImageResource(R.drawable.party_message)
            mBinding.emoji.setImageResource(R.drawable.party_emoji)
            mBinding.ivMessage.setImageResource(R.drawable.party_message2)
            mBinding.ivMore.setImageResource(R.drawable.party_more)

            mSkinMikeOpen = null
            mSkinMikeClose = null
            mSkinMikeBan = null
        }
        mikeStateUI()
    }

    private fun initListener() {
        //发送消息
        mBinding.sendr.setOnSingleClickListener {
            mBuilder.sendrBack?.invoke()
        }
        //麦克风
        mBinding.mike.setOnSingleClickListener {
            if (mikeStateData.value != 2) {
                val mike = if (mikeStateData.value == 0) {
                    1
                } else {
                    0
                }
                setMikeState(mike)
                mBuilder.mikeStateBack?.invoke(mike)
            } else {
                ToastGravity.showGravity(com.polaris.live.translation.R.string.homeowner_banned_speaking_voice)
            }
        }
        //表情
        mBinding.emoji.setOnSingleClickListener {
            mBuilder.emojiBack?.invoke()
        }
        //消息
        mBinding.message.setOnSingleClickListener {
            mBuilder.messageBack?.invoke()
        }
        //游戏
        mBinding.game.setOnSingleClickListener {
            mBuilder.gameBack?.invoke()
        }
        //管理
        mBinding.setting.setOnSingleClickListener {
            mBuilder.settingBack?.invoke()
        }
        //礼物
        mBinding.gift.setOnSingleClickListener {
            mBuilder.giftBack?.invoke()
        }
        //免费礼物
        mBinding.widgetCircleGift.setOnClickGiftListener {
            mBuilder.freeGiftBack?.invoke(it)
        }
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        lifecycleRegistry.currentState = Lifecycle.State.CREATED
        initData()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
        freeGiftJob?.cancel()
        freeGiftJob = null
        newEmojiJob?.cancel()
        newEmojiJob = null
    }

    override fun onWindowVisibilityChanged(visibility: Int) {
        super.onWindowVisibilityChanged(visibility)
        if (visibility == VISIBLE) {
            lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
            lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
        } else if (visibility == GONE || visibility == INVISIBLE) {
            lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
            lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
        }
    }

    class Builder {

        //显示发送消息按钮
        var showSendr = false
        var sendrBack: (() -> Unit)? = null

        //显示麦克风按钮
        var showMike = false
        var mikeBack: (() -> Unit)? = null

        //麦克风开关状态
        var mikeState = 0
        var mikeStateBack: ((b: Int) -> Unit)? = null

        //显示表情按钮
        var showEmoji = false
        var emojiBack: (() -> Unit)? = null

        //显示消息按钮
        var showMessage = false
        var messageBack: (() -> Unit)? = null

        //显示游戏按钮
        var showGame = false
        var gameBack: (() -> Unit)? = null

        //显示礼物
        var showGift = false
        var giftBack: (() -> Unit)? = null

        //显示管理
        var showSetting = false
        var settingBack: (() -> Unit)? = null

        var sourceType: Int = 0 //礼物来源
        var freeGiftBack: ((UserFreeGiftResp) -> Unit)? = null

        fun setShowSendrButton(showSendr: Boolean): Builder {
            this.showSendr = showSendr
            return this
        }

        fun setSendrClickBack(
            back: () -> Unit,
        ): Builder {
            sendrBack = back
            return this
        }

        fun setShowMikeButton(showMike: Boolean): Builder {
            this.showMike = showMike
            return this
        }

        fun setMikeClickBack(
            back: () -> Unit,
        ): Builder {
            mikeBack = back
            return this
        }

        /**
         * 麦位状态
         * * 0闭麦 1开麦 2禁麦
         */
        fun setMikeState(mike: Int): Builder {
            mikeState = mike
            return this
        }

        fun setMikeStateBack(
            back: (b: Int) -> Unit,
        ): Builder {
            mikeStateBack = back
            return this
        }

        fun setShowEmojiButton(showEmoji: Boolean): Builder {
            this.showEmoji = showEmoji
            return this
        }

        fun setEmojiClickBack(
            back: () -> Unit,
        ): Builder {
            emojiBack = back
            return this
        }

        fun setShowMessageButton(
            showMessage: Boolean,
        ): Builder {
            this.showMessage = showMessage
            return this
        }

        fun setMessageClickBack(
            back: () -> Unit,
        ): Builder {
            messageBack = back
            return this
        }

        fun setShowGameButton(showGame: Boolean): Builder {
            this.showGame = showGame
            return this
        }

        fun setGameClickBack(back: () -> Unit): Builder {
            gameBack = back
            return this
        }

        fun setShowGiftButton(showGift: Boolean): Builder {
            this.showGift = showGift
            return this
        }

        fun setGiftClickBack(back: () -> Unit): Builder {
            giftBack = back
            return this
        }

        fun setShowSettingButton(showSetting: Boolean): Builder {
            this.showSetting = showSetting
            return this
        }

        fun setSettingClickBack(back: () -> Unit): Builder {
            settingBack = back
            return this
        }

        fun setFreeGiftSourceType(sourceType: Int): Builder {
            this.sourceType = sourceType
            return this
        }

        fun setFreeGiftClickBack(back: (UserFreeGiftResp) -> Unit): Builder {
            freeGiftBack = back
            return this
        }
    }

    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }
}
